﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GalaSoft.MvvmLight.Command;
using System.Windows.Media;
using System.Windows.Forms;
using System.Threading;
using System.Windows.Threading;
using System.Windows;
using System.Windows.Forms;
using TriviaViewModel.ServiceReference1;
using GalaSoft.MvvmLight;
using System.Windows.Input;
using GalaSoft.MvvmLight.Messaging;




namespace TriviaViewModel
{
    public class GameViewModelWizard : ViewModelBase
    {
        #region local proerties
        private int clueCommandExacute = 0;
        private List<int> _timeScore = new List<int>();
        private int timeInt;
        private DispatcherTimer timer;
        private string _userName;
        private string _password;
        private int _questionIndex = 0;
        #endregion


        #region class methods
        /// <summary>
        /// method that called from the WizardViewBase class and initiates question and answers of the game
        /// </summary>
        /// <param name="difficulty"></param>
        /// <param name="topic"></param>
        public bool SetQuestionsAndAnswers(string difficulty, string topic)
        {

            bool returnval = false;
            using (var proxy = new ServiceReference1.GameServiceClient())
            {
                
                _gameQuestions = proxy.GetQusetions(difficulty, topic).ToList();
                foreach (var item in _gameQuestions)
                {
                    if (item.Answers != null)
                    {
                        foreach (var item1 in item.Answers)
                            _gameAnswers.Add(item1);
                    }
                }
                if (_gameQuestions.Count > 0 && _gameAnswers.Count > 0)
                {
                    CurrentQuestion = _gameQuestions[_questionIndex];
                    QuestionAnswers = _gameAnswers.Where(item => item.QuestionId == CurrentQuestion.Id).ToList();
                    returnval = true;
                }
            }
            return returnval;
        }
        /// <summary>
        /// Initiates the timer of the class
        /// </summary>
        public void StartTimer()
        {
            timer = new DispatcherTimer();
            timeInt = 60;
            timer.Tick += new EventHandler(CahngeTime);
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Start();
        }
        /// <summary>
        /// sets the appearance of time in the game window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void CahngeTime(object sender, EventArgs e)
        {
            timeInt--;
            Time = (timeInt < 10) ? "00 : 0" + timeInt.ToString() : "00: " + timeInt.ToString();

            if (timeInt == 0)
                NextQuestionCommandExecute();
        }

        /// <summary>
        /// sets the user that plays the game
        /// </summary>
        /// <param name="UsereNam"></param>
        /// <param name="Password"></param>
        internal void SetUser(string UsereNam, string Password)
        {
            bool exists;
            _userName = UsereNam;
            _password = Password;
            using (var proxy = new GameServiceClient())
            {
                exists = proxy.InsertUser(_userName, _password);
            }
            string str = (exists) ? "Welcome Back " + UsereNam : "Welcome " + UsereNam;

            System.Windows.Forms.MessageBox.Show(str);
        }
        #endregion

        #region properties

        private Visibility _isClueVisible;
        public Visibility IsClueVisible
        {
            get { return _isClueVisible; }
            set
            {
                if (_isClueVisible != value)
                {
                    _isClueVisible = value;
                    RaisePropertyChanged("IsClueVisible");
                }
            }
        }

        private Visibility _isLableVisible;
        public Visibility IsLableVisible
        {
            get { return _isLableVisible; }
            set
            {
                if (_isLableVisible != value)
                {
                    _isLableVisible = value;
                    RaisePropertyChanged("IsLableVisible");
                }

            }
        }

        private Visibility _isGameFinished;
        public Visibility IsGameFinished
        {
            get { return _isGameFinished; }
            set
            {
                if (_isGameFinished != value)
                {
                    _isGameFinished = value;
                    RaisePropertyChanged("IsGameFinished");
                }
            }
        }

        private Visibility _isAnswerVisible;
        public Visibility IsAnswersVisible
        {
            get { return _isAnswerVisible; }
            set
            {
                if (_isAnswerVisible != value)
                {
                    _isAnswerVisible = value;
                    RaisePropertyChanged("IsAnswersVisible");
                }
            }
        }

        private string _time;
        public string Time
        {
            get { return _time; }
            set
            {
                if (_time != value)
                {
                    _time = value;
                    RaisePropertyChanged("Time");
                }

            }
        }

        private List<AnswerCalss> _gameAnswers;
        private List<QuestionCalss> _gameQuestions;

        private QuestionCalss _currentQuestion;
        public QuestionCalss CurrentQuestion
        {
            get { return _currentQuestion; }
            set
            {
                if (_currentQuestion != value)
                {
                    _currentQuestion = value;
                    RaisePropertyChanged("CurrentQuestion");
                }
            }
        }

        private List<AnswerCalss> _questionAnswers;
        public List<AnswerCalss> QuestionAnswers
        {
            get { return _questionAnswers; }
            set
            {
                if (_questionAnswers != value)
                {
                    _questionAnswers = value;
                    RaisePropertyChanged("QuestionAnswers");
                }
            }
        }

        private AnswerCalss _selectedAnswer;
        public AnswerCalss SelectedAnswer
        {
            get { return _selectedAnswer; }
            set
            {
                var proxy = new GameServiceClient();
                if (_selectedAnswer != value)
                {
                    _selectedAnswer = value;
                    proxy.IsTheAnswerRightCompleted += (s, e) =>
                    {
                        IsLableVisible = Visibility.Visible;
                        IsAnswersVisible = Visibility.Hidden;
                        SelectedAnswer.IsRightAnswer = e.Result;

                        RaisePropertyChanged("SelectedAnswer");

                    };
                    if (_selectedAnswer != null && _selectedAnswer.AnswerString != null)
                        proxy.IsTheAnswerRightAsync(SelectedAnswer.Id,SelectedAnswer.QuestionId);
                    else
                        RaisePropertyChanged("SelectedAnswer");
                }


            }


        }


        #endregion

        #region Commands
        public ICommand NextQuestionCommand { get; set; }
        public ICommand ShowClueCommand { get; set; }
        #endregion


        public GameViewModelWizard()
        {
            StartTimer();
            IsGameFinished = Visibility.Collapsed;
            _gameQuestions = new List<QuestionCalss>();
            _gameAnswers = new List<AnswerCalss>();
            QuestionAnswers = new List<AnswerCalss>();
            IsClueVisible = Visibility.Collapsed;
            IsLableVisible = Visibility.Collapsed;
            ShowClueCommand = new RelayCommand(() => ShowClueCommandExecute());
            NextQuestionCommand = new RelayCommand(() => NextQuestionCommandExecute());

        }

        #region command executes
        /// <summary>
        /// sets clue label visibility
        /// </summary>
        private void ShowClueCommandExecute()
        {
            clueCommandExacute++;
            IsClueVisible = (clueCommandExacute % 2 == 0) ? Visibility.Collapsed : Visibility.Visible;
        }

        /// <summary>
        /// method that checks answer for current questions and sets parameters for the next question
        /// </summary>
        public void NextQuestionCommandExecute()
        {
          
            IsClueVisible = Visibility.Collapsed;
            var proxy = new ServiceReference1.GameServiceClient();
            if (_questionIndex + 1 < _gameQuestions.Count)
            {
                NextQuestionIntialization();
                IsAnswersVisible = Visibility.Visible;
                IsLableVisible = Visibility.Hidden;

                if (SelectedAnswer != null)
                {
                    proxy.IsTheAnswerRightCompleted += (s, e) =>
                    {
                        SelectedAnswer.IsRightAnswer = e.Result;
                        if (SelectedAnswer.IsRightAnswer == true)
                            _timeScore.Add(timeInt);
                    }; proxy.IsTheAnswerRightAsync(SelectedAnswer.Id,SelectedAnswer.QuestionId);
                }
            }

            else if (_questionIndex + 1 == _gameQuestions.Count)
            {
                _questionIndex++;
                int score = 0;
                if (SelectedAnswer != null)
                {
                    proxy.IsTheAnswerRightCompleted += (s, e) =>
                        {
                            SelectedAnswer.IsRightAnswer = e.Result;
                            if (SelectedAnswer.IsRightAnswer == true)
                                _timeScore.Add(timeInt);

                            if (_timeScore.Count > 0)
                            {
                                score = (_userName != null && _password != null) ? proxy.CalcAndGetScore(_timeScore.ToArray(), _userName, _password) :
                                    proxy.CalcAndGetScore(_timeScore.ToArray(), null, null);
                            }
                            EndGameMethod(score);

                        };
                    proxy.IsTheAnswerRightAsync(SelectedAnswer.Id,SelectedAnswer.QuestionId);
                }
                else if (_timeScore.Count > 0)
                {
                    score = (_userName != null && _password != null) ? proxy.CalcAndGetScore(_timeScore.ToArray(), _userName, _password) :
                        proxy.CalcAndGetScore(_timeScore.ToArray(), null, null);
                    EndGameMethod(score);
                }
                else
                    EndGameMethod(score);
            }
           
        }
        /// <summary>
        /// method that sets the properties of the end of the game.
        /// </summary>
        /// <param name="score"></param>
        private void EndGameMethod(int score)
        {
            System.Windows.Forms.MessageBox.Show("Your Score Is " + score.ToString());
            timer = null;
            IsAnswersVisible = Visibility.Collapsed;
            IsGameFinished = Visibility.Visible;
            IsLableVisible = Visibility.Collapsed;
            this.Dispose();
        
        }
        public void EndGameOutside()
        {
            this.timer = null;
            this.Dispose();
        }

        /// <summary>
        /// initializes he parameters for next question
        /// </summary>
        private void NextQuestionIntialization()
        {

            _questionIndex++;
            CurrentQuestion = _gameQuestions[_questionIndex];
            QuestionAnswers = _gameAnswers.Where(item => item.QuestionId == CurrentQuestion.Id).ToList();
            StartTimer();
        }
        #endregion



    }
}
